package org.joinme.backend.service;

import org.joinme.backend.mapper.CarPoolingRecordMapper;
import org.joinme.backend.mapper.ParticipateRecordMapper;
import org.joinme.backend.mapper.WechatUserMapper;
import org.joinme.backend.model.CarPoolingRecord;
import org.joinme.backend.model.ParticipateRecord;
import org.joinme.backend.model.WechatUser;
import org.joinme.backend.util.ConstUtil;
import org.joinme.backend.util.ErrorCodeMsg;
import org.joinme.backend.util.PrjException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ParticipateService {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private CarPoolingRecordMapper carPoolingRecordMapper;

    @Autowired
    private ParticipateRecordMapper participateRecordMapper;

    @Autowired
    private WechatUserMapper wechatUserMapper;

    //添加参与记录
    public boolean addParticipateRecord(ParticipateRecord record){
        if(participateRecordMapper.insertSelective(record) > 0){
            return true;
        }
        return false;
    }

    //更新参与记录
    public boolean updateParticipateRecord(ParticipateRecord record){
        if(participateRecordMapper.updateByPrimaryKeySelective(record) > 0){
            return true;
        }
        return false;
    }

    //更新所有相关的参与记录为指定状态
    public boolean updateAllRelatedStatus(int carPoolingId, int participateStatus){
        if(participateRecordMapper.updateAllRelatedStatus(carPoolingId,participateStatus) > 0)
            return true;
        return false;
    }

    //取消参与记录
    public int cancelParticipate(int userId, int carPoolingId) throws PrjException{
        int result = 0;
        ParticipateRecord participateRecord = participateRecordMapper.selectByPrimaryKey(userId, carPoolingId);
        CarPoolingRecord record = carPoolingRecordMapper.selectByPrimaryKey(carPoolingId);
        if(participateRecord == null){
            throw new PrjException(ErrorCodeMsg.CAR_POOLING_RECORD_COMPLETE_ERROR);
        }
        participateRecord.setParticipateStatus(ConstUtil.PARTICIPATE_ABORTED);
        result = participateRecordMapper.updateByPrimaryKeySelective(participateRecord);
        //参与者取消
        if(participateRecord.getParticipateRole() == ConstUtil.ROLE_PARTICIPANT){
            log.info("参与者取消");
            record.setCurrentNum(record.getCurrentNum() - 1);
            result = carPoolingRecordMapper.updateByPrimaryKeySelective(record);
        }
        //发布者取消
        else{
            log.info("创建者取消");
            //没有其他参与人员时，直接置为放弃状态
            if(record.getCurrentNum() == 1){
                log.info(String.format("There is only the publisher himself. Cancel directly."));
                record.setCarPoolingStatus(ConstUtil.CARPOOLING_ABORTED);
                return carPoolingRecordMapper.updateByPrimaryKeySelective(record);
            }
            record.setCurrentNum(record.getCurrentNum() - 1);
            result = carPoolingRecordMapper.updateByPrimaryKeySelective(record);
            //更新角色为参与者，以便新设定一个创建者角色
            participateRecord.setParticipateRole(ConstUtil.ROLE_PARTICIPANT);
            participateRecordMapper.updateByPrimaryKeySelective(participateRecord);
            List<WechatUser> participants = wechatUserMapper.selectParticipantsByCarPoolingId(carPoolingId);
            int newCreatorId = -1;
            for(WechatUser user : participants){
                if(user.getUserId() != userId){
                    newCreatorId = user.getUserId();
                    break;
                }
            }
            //将newCreatorId对应的用户设定为创建者
            log.info(String.format("User with id [%d] is selected to be the new publisher.", newCreatorId));
            ParticipateRecord newRecord = participateRecordMapper.selectByPrimaryKey(newCreatorId,carPoolingId);
            newRecord.setParticipateRole(ConstUtil.ROLE_PUBLISHER);
            result = participateRecordMapper.updateByPrimaryKeySelective(newRecord);
        }

        return result;
    }
}
